/**
 * 
 */
package gates.internals;

import java.util.ArrayList;
import java.util.List;
import java.util.Observable;

/**
 * @author denis
 * 
 */
public class NBaseTransistor extends Transistor implements ITransistor {

	public NBaseTransistor() {
	}

	public NBaseTransistor(String name, int defect) {
		base = new Base();
		emitter = new Emitter();
		collector = new Collector();
		defective = defect == 1;
		base.addObserver(emitter);
		this.name = name;
		// emitter.addObserver(collector);
	}

	class Base extends Transistor.Base {
		private List<Gate> inputs = new ArrayList<Gate>();

		public void update(Observable o, Object arg) {
			if (((Boolean) arg) == true) {
				if (o instanceof Gate && !inputs.contains(o))
					inputs.add((Gate) o);
				this.switchGate(false);
			}
			if (((Boolean) arg) == false) {
				if (o instanceof Gate && inputs.contains(o)) {
					inputs.remove(o);
				}
				if (inputs.isEmpty())
					this.switchGate(true);
			}
		}

		public boolean value() {
			return on;
		}
	}

	public class Emitter extends Transistor.Emitter {
		public void update(Observable o, Object arg) {
			if (o instanceof Base) {
				if (collector.isOn() == null) {
					return;
				}
				if (defective) {
					System.out.println("Defective: " + NBaseTransistor.this.toString());
					if (oldValue == null) {
						System.out
								.println("Defective transistor with no oldValue, not transmitting anything!"
										+ NBaseTransistor.this.toString());
					} else {
						switchGate(oldValue);
					}
				} else {
					switchGate((Boolean) arg && collector.isOn());
				}
			} else if (o instanceof Collector && (Collector) o != collector) {
				switchGate((Boolean) arg);
			}
		}

		public boolean value() {
			return on;
		}
	}

	public class Collector extends Transistor.Collector {
		public void update(Observable o, Object arg) {
			switchGate((Boolean) arg);
		}

		public boolean value() {
			return on;
		}
	}

	@Override
	public String toString() {
		return "nbTransistor " + name;
	}
}
